![]() | |
|
|
|
To access the contents, click the chapter and section titles.
Bug Proofing Visual Basic: A Guide to Error Handling and Prevention
This is an even bigger problem if the routine declares other variables far from its beginning, a practice I do not recommend. For example, in the following code the variables i and j are both static.
Static Private Sub MyStaticRoutine()
Dim i As Integer
:
Lots of code.
:
Dim j As Integer
:
End Sub
In cases like this, the static keyword may not be visible on the screen so the reader may assume incorrectly that j is not static. Make static variables obvious by declaring them static individually. Use Private and PublicWithin a subroutine, the Dim statement declares a variable with scope limited to that routine. At the module level, the Dim statement declares a variable with scope limited to that module. However, scope is somewhat inconsistent if you do not use Private or Public when you declare variables and routines. Variables declared with Dim are private to the module. Subroutines, functions, and property procedures declared with neither Private nor Public are public and available outside the module. To make the code obvious, always use Private and Public instead of Dim when you declare symbols at the module level. This includes routines, variables, constants, types, and enumerated values. Using Private and Public makes a symbols scope obvious.
This type is defined only within the module.
Private Type PrivateType
:
End Type
This type is defined within the whole program.
Public Type PublicType
:
End Type
This variable is defined only within the module.
Private PrivateVariable As Integer
This variable is defined within the whole program.
Public PublicVariable As Integer
This subroutine is defined only within the module.
Private Sub PrivateSub()
:
End Sub
This function is defined within the whole program.
Public Function PublicFunction() As Integer
:
End Sub
Using Private and Public makes a symbols scope obvious. Use ByVal and ByRefWhen you declare a routines parameter with the ByVal (by value) keyword, any changes the routine makes will not be returned to the calling routine. The routine works with a separate copy of the parameter so changes are lost when the routine ends. When you declare a routines parameter with the ByRef (by reference) keyword, any changes the routine makes are returned to the calling routine. The routine uses the same copy of the variable as the caller so any changes it makes are permanent. If you declare a parameter with neither ByVal nor ByRef, Visual Basic passes the value by reference. Not only is this not obvious, it is also usually the wrong option. Passing an argument ByVal protects the calling routine from accidental changes to the parameter. To make the caller as safe as possible, every parameter should be passed by value unless part of the routines purpose is to explicitly change the value of the parameter. Use ByVal whenever possible. Use ByRef to emphasize the fact that a parameter may be changed by the routine. This makes it obvious that the value may change, and it makes it obvious that you did not simply forget to declare the parameter ByVal. The following code declares a subroutine that modifies its second parameter but not its first.
Private Sub MyRoutine(ByVal num_employees As Integer, _
ByRef num_jobs As Integer)
:
Note that arrays must always be passed ByRef. Visual Basic does this for efficiency reasons. When you pass a parameter ByVal, Visual Basic makes a separate copy of the value for the routine to manipulate. Copying a large array can take a long time, so Visual Basic passes it by reference instead of by value. If you do not intend to modify the entries in an array parameter, you can leave the ByRef off to hint that you do not intend to change the values. Visual Basic will not stop the routine from changing them, however.
Print a list of employees without modifying the list.
Private Sub PrintEmployees(employees() As String)
:
One confusing case still occurs when the calling routine passes a value that cannot be modified as a ByRef parameter; for example, if the calling routine uses the value 10 as in the following code. The called routine cannot really modify the value 10 and return the modified result to the calling routine since the value is not stored in a variable.
SetTemperature 10, 20
:
Change the temperature. Return the previous temperature
through the temperature parameter.
Private Sub SetTemperature(ByRef temperature As Integer, _
ByVal duration As Integer)
:
In this situation, Visual Basic creates a temporary variable and places the value 10 in it. Even if the routine modifies the temporary variable, the calling routine will not see the effect. This is a reasonable course for Visual Basic to take, but it may indicate a bug in the calling routine. The called routine changes its parameter for a reason. Ignoring the change indicates a possible mistake by the caller. Try not to pass unchangeable values into routines as ByRef parameters. Visual Basic will not warn you if you do, but this may cause a misunderstanding. Use Line ContinuationIf a line gets too long, it may not be obvious that some of it extends beyond the edge of the window. This can be very confusing. Even after the reader realizes there is more to the command, he must scroll the code window back and forth to read the entire statement. The added distraction makes it harder to understand the code. It also prevents the reader from seeing all of the adjacent lines at the same time. Use line continuation characters to make each line completely visible. Use indentation to show that the subsequent lines are part of the same statement. Unless your project standardizes on a certain size monitor and everyone works with maximized code windows, you should assume the code window is relatively small. Break lines soon enough that the line continuation characters are visible. If that character is hidden, the statement may look like two separate commands. Proper indentation can warn the reader that something unusual is happening, but the reader may still become confused. Break long single-line If statements before the Then keyword. This makes it more obvious that the next line is part of the If statement. For example, consider the following statement:
If num_processed < num_employees Then _
ProcessEmployee
Now suppose another programmer wants to add a new statement that keeps the user posted about the programs progress. If the programmer does not notice the line continuation character, he might make the change like this:
If num_processed < num_employees Then _
ProcessEmployee
UpdateStatusBar
At a quick glance, this looks correct, but the new UpdateStatusBar command is not contained within the If statement. The scope of the If statement is obvious if the original code is broken before the Then keyword like this:
If num_processed < num_employees _
Then ProcessEmployee
Even if the reader does mistakenly add a new line thinking it will lie within the If statement, the result looks suspicious. It is easier to notice that there is a mistake in the following code than it is in the previous incorrect version.
If num_processed < num_employees _
Then ProcessEmployee
UpdateStatusBar
An even better solution is to make long If statements use multiple lines. The difference in performance is tiny and the code is much more obvious.
If num_processed < num_employees Then
ProcessEmployee
UpdateStatusBar
End If
|
|
Products | Contact Us | About Us | Privacy | Ad Info | Home
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-1999 EarthWeb Inc. All rights reserved. Reproduction whole or in part in any form or medium without express written permision of EarthWeb is prohibited.
|